#'
#' define a population object
#'
#'
#' @param species a name for the population
#' @param x,y a numeric vector contains spatial location of the individuals
#' @param valid_check a logical flag to check the validation of spatial coordination and species name
#' @param traits a dataframe with individual-based traits, such as DBH, alive et al.
#' 
#' @details
#' The population object is just a simple warp of a data frame with columns named 
#' 'x', 'y'. There is only one aditional information about plot range stored in 'plotdim' 
#' attribute of the community object.
#'
#' The population is considered as valid, if
#' 
#'1. The x, y columns should not contain missing values
#'
#'2. all columns with numeric values should not contain infinite numbers
#'
#'3. all columns moust have the same length.
#'
#'4. spatial locations of individuals can not be overlapped
#'
#'5. The Species name is defined.
#'
#'6. all of individuals distributed within the plot.
#'
#'
#' @return
#' A population object contains two columns:
#' 
#' \itemize{
#' \item x
#' \item y
#' }
#' 
#' And species name attribute 'species', a plot range value in its attribute 'plotdim'.
#' 
#' 
#' @examples
#' 
#' species="sp1"
#' plotdim=c(10,8)
#' x=runif(20,0,plotdim[1])
#' y=runif(20,0,plotdim[2])
#' 
#' pop=population(species,x,y,plotdim)
#' 
#' pop
#' 
#' 
#' @export
population=function(species,x,y,plotdim,valid_check=TRUE,traits=NULL){
  
  if(valid_check)
    is_valid_coordinate(x,y,plotdim)
  
  species=unique(species)
  if(length(species)>1)
    stop("only one species name can be defined for a population")
  
  pop=data.frame(x=x,y=y)
  if(!is.null(traits)){
    if(!is.data.frame(traits)) stop("the given traits is not a data frame")
    
    if(dim(traits)[1]!=length(x)) stop("the number of trait row does not equal to the number of individuals")
    
    tnames=colnames(traits)
    if("dbh" %in% tnames){
      if(!is.numeric(traits$dbh))
        warning("Values in the DBH column of traits are not numeric")
    }
    #TODO check validation for each trait type
    pop=cbind(pop,traits)    #combine the trait columns
  }
  
  attr(pop,"species")=species
  attr(pop,"plotdim")=plotdim
  class(pop)=c("population",class(pop))
  return(pop)
}

#' @export
print.population=function(pop){
  plotdim=attr(pop,"plotdim")
  cat(paste("A individual-mapped ", attr(pop,"species")," population with \n"))
  cat(paste(total_abundance(pop),"individuals in a",plotdim[1],"*",plotdim[2],"rectangle region \n"))
}

#convert from community with one species into a population
as.population=function(com){
  if(total_richness(com)!=1){
    stop("Can't convert it into a population, because there are more than one species")
  }
  plotdim=attr(com,"plotdim")
  class(com)="data.frame"
  species=com$species[1]
  pop=com[,-1] #remove the first species column
  attr(pop,"species")=as.character(species)
  attr(pop,"plotdim")=plotdim
  class(pop)=c("population",class(pop))
  return(pop)
}
